function varargout = RFNN(varargin)
% RFNN MATLAB code for RFNN.fig
%      RFNN, by itself, creates a new RFNN or raises the existing
%      singleton*.
%
%      H = RFNN returns the handle to a new RFNN or the handle to
%      the existing singleton*.
%
%      RFNN('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in RFNN.M with the given input arguments.
%
%      RFNN('Property','Value',...) creates a new RFNN or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before RFNN_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to RFNN_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help RFNN

% Last Modified by GUIDE v2.5 06-Nov-2012 20:14:29

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @RFNN_OpeningFcn, ...
                   'gui_OutputFcn',  @RFNN_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
end

% --- Executes just before RFNN is made visible.
function RFNN_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to RFNN (see VARARGIN)

% Choose default command line output for RFNN
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes RFNN wait for user response (see UIRESUME)
% uiwait(handles.RFNN);
end

% --- Outputs from this function are returned to the command line.
function varargout = RFNN_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;
end


% --- Executes on button press in btnConfig.
function btnConfig_Callback(hObject, eventdata, handles)
% hObject    handle to btnConfig (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    h = figure(Config);
    waitfor(h);
   
    info_array = get(handles.RFNN, 'UserData');
    if(not(isempty(info_array)))
        handles.info = info_array;
        guidata(hObject,handles);
        msgbox('Variable saved','Saved');
        disp('OK');
        set(handles.btnRun,'Enable','on');
    end
end

% --- Executes on button press in btnRun.
function btnRun_Callback(hObject, eventdata, handles)
% hObject    handle to btnRun (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
  
    % Convert output y
    yy = handles.y;
    tempY = zeros(size(handles.y,1),10);
    for i =1:size(handles.y,1)
        t = zeros(1,10);
        t(yy(i)+1) = 1;
        tempY(i,:) = t;
    end
    handles.y = tempY;
    guidata(hObject,handles);
%get config information.
    vectorInit = handles.info;
    M_rules = int32(vectorInit(3)); % number of rules
    N = int32(vectorInit(1));  %number of input.
    P = int32(vectorInit(2));
    %first layer have N  nodes N = 400
    % second layer have N x M nodes
    % third layer have M nodes
    % final layer have 10 nodes.
    w = zeros(M_rules,P);    % Trong so w between layer 3 and layer 4
    m = zeros(N,M_rules);           % Trong tam  of Gauss
    xichma = ones(N,M_rules);      % Do rong xichma of Gauss because divide we must init it value 1.
    theta = zeros(N,M_rules);       % Thong so hoi tiep. trong layer 2
    
    
    
    % Algorigthm.
    % Find value yk.
    % Find Error.
    % Update parameter.
    
    output2 = zeros(N,M_rules);
    output3 = zeros(1,M_rules); % 1 vector M phan tu.
    output4 = zeros(1,P);
    
    iCount = 0;
    
    %Trainning tren 90 percent bo du lieu.
    % 10percent de test
    iNum = 0.1 * size(handles.X,1);
for i=1:1:iNum      % Lap tren 4500 bo
        
     for currSet = 1:10   % Moi set lap 10 lan.
      iCount = iCount + 1;
      x = handles.X;
      % Tinh output layer 1
      output1 = x(i,:);
      
      %Tinh output layer 2 tai thoi diem (t). 
      
      tempOutput2 = output2;  % save value at time (t-1)
      for ii = 1:N
          for jj = 1:M_rules
             output2(ii,jj) = exp(-(output1(ii) + theta(ii,jj)*tempOutput2(ii,jj) - m(ii,jj) )/xichma(ii,jj)^2);
          end
      end
      
      % Tinh output layer 3
      
      for jj = 1:M_rules
          S = 1;
          for ii =1:N
              S = S * output2(ii,jj);
          end
          output3(1,jj) = S;  
      end
      
      % Tinh output 4. Result 
      
      for k = 1:P
              output4(1,k) = dot(output3(1,:),w(:,k));
      end
      
      % Calculate error.
      % change output y. Remember.
      E = 0.5 * dot((output4 - tempY(i)),(output4 - tempY(i)));
      %plot 
      figure(3);
      plot(iCount,E);
      
      tempW = w; 
      tempM = m; 
      tempXichma = xichma;
      tempTheta = theta;
      % Cap nhat trong so w
      for k = 1:P
          w(:,k) = tempW(:,k) + reshape(output3(1,:),M_rules,1).*(vectorInit(7)* E);
      end
      
      % Cap nhat trong so m.
      for ii =1:N
          for jj = 1:M_rules
              % Be careful with S output2
              S = output3(jj)*2*(output1(ii) + tempOutput2(ii,jj)*tempTheta(ii,jj) - tempM(ii,jj))/(tempXichma(ii,jj)^2);
              tempS = 0;
              for kk = 1:P
                  tempS = tempS + tempW(jj,kk)*S;
              end
              m(ii,jj) = tempM(ii,jj) + vectorInit(4)*E*tempS;
          end
      end
      
      %Cap nhat gia tri xichma.
      for ii =1:N
          for jj = 1:M_rules
              % Be careful with S output2
              S = output3(jj)*2*(output1(ii) + tempOutput2(ii,jj)*tempTheta(ii,jj) - tempM(ii,jj))^2/(tempXichma(ii,jj)^3);
              tempS = 0;
              for kk = 1:P
                  tempS = tempS + tempW(jj,kk)*S;
              end
              theta(ii,jj) = tempTheta(ii,jj) + vectorInit(5)*E*tempS; %nhan voi learning rate cua xichma
          end
      end
      
      
      
      %Cap nhat gia tri theta
      for ii =1:N
          for jj = 1:M_rules
              % Be careful with S output2
              S = -2*(output1(ii) + tempOutput2(ii,jj)*tempTheta(ii,jj) - tempM(ii,jj))*tempOutput2(ii,jj)/(tempXichma(ii,jj)^2);
              tempS = 0;
              for kk = 1:P
                  tempS = tempS + tempW(jj,kk)*S;
              end
              xichma(ii,jj) = tempXichma(ii,jj) + vectorInit(6)*E*tempS; %nhan voi learning rate cua xichma
          end
      end
      
      
      % Sau khi cap nhat cac gia tri. Cap nhat lai tat ca.
      
      tempW = w;
      tempM = m;
      tempXichma = xichma;
      tempTheta = theta;
      tempOutput2 = output2;
      
     end
end
    %Sau khi da tinh xong thi het chuong trinh




end

% --------------------------------------------------------------------
function menuFile_Callback(hObject, eventdata, handles)
% hObject    handle to menuFile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
end


% --------------------------------------------------------------------
function menuLoad_Callback(hObject, eventdata, handles)
% hObject    handle to menuLoad (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    [FileName,FilePath]=uigetfile();
    ExPath = [FilePath FileName];
    x = load(ExPath); % get X,Y. X is matrix 5000x400
    handles.X = x.X;
    handles.y = x.y;
    guidata(hObject,handles);
   % tableData
   %f = figure('Name','fuck','Position', [100 100 752 350]);
   % h = get(handles.tableData);
   %set(h,'Columns',10);
   %t = uitable('Tag','TableData','Parent', RFNN, 'Position', [10 10 752 350]);
   set(handles.datatable,'Data',x.X);
   %get 1 row. to show image.
   % reshape matrix.
   m = reshape(x.X(501,:),20,20);
   figure(2);
   imshow(m);
   set(handles.btnConfig,'Enable','on');
   %TODO
   
end

% --------------------------------------------------------------------
function Exit_Callback(hObject, eventdata, handles)
% hObject    handle to Exit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    close(RFNN);
end


% --- If Enable == 'on', executes on mouse press in 5 pixel border.
% --- Otherwise, executes on mouse press in 5 pixel border or over btnConfig.
function btnConfig_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to btnConfig (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    
end
